package com.molichuxing.gateway.api.services.impl;

import java.util.List;
import java.util.Map;

import javax.annotation.Resource;
import javax.validation.Valid;

import org.apache.commons.lang3.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;

import com.molichuxing.framework.dto.Paged;
import com.molichuxing.framework.exception.BizException;
import com.molichuxing.framework.result.ResponseResult;
import com.molichuxing.framework.utils.DateUtil;
import com.molichuxing.framework.utils.ObjectCastUtil;
import com.molichuxing.gateway.api.config.OptionalLogConfig;
import com.molichuxing.gateway.api.services.PermissionApiService;
import com.molichuxing.gateway.bff.permission.entity.response.AccountCreateVo;
import com.molichuxing.gateway.bff.permission.entity.response.AccountLoginLogVo;
import com.molichuxing.gateway.bff.permission.entity.response.AccountLoginVo;
import com.molichuxing.gateway.bff.permission.entity.response.AccountModifyVo;
import com.molichuxing.gateway.bff.permission.entity.response.AccountVo;
import com.molichuxing.gateway.bff.permission.entity.response.DesenseVo;
import com.molichuxing.gateway.bff.permission.entity.response.GroupBindResourceVo;
import com.molichuxing.gateway.bff.permission.entity.response.GroupBindVo;
import com.molichuxing.gateway.bff.permission.entity.response.GroupCreateVo;
import com.molichuxing.gateway.bff.permission.entity.response.GroupModifyVo;
import com.molichuxing.gateway.bff.permission.entity.response.GroupVo;
import com.molichuxing.gateway.bff.permission.entity.response.ModifyPassowrdVo;
import com.molichuxing.gateway.bff.permission.entity.response.OpGroupAndIovGroupVo;
import com.molichuxing.gateway.bff.permission.entity.response.OperationLogVo;
import com.molichuxing.gateway.bff.permission.entity.response.TabVo;
import com.molichuxing.gateway.bff.permission.services.AccountBffService;
import com.molichuxing.gateway.bff.permission.services.GroupBffService;
import com.molichuxing.gateway.bff.permission.services.OperationLogBffService;
import com.molichuxing.gateway.bff.permission.services.ResourceBffService;
import com.molichuxing.gateway.utils.TokenUtil;
import com.molichuxing.services.infrastructure.dto.response.response.ResourceDto;
import com.molichuxing.services.infrastructure.service.IovPermissionService;
import com.molichuxing.services.property.SystemTypeEnum;

import io.swagger.annotations.Api;
import io.swagger.annotations.ApiImplicitParam;
import io.swagger.annotations.ApiImplicitParams;
import io.swagger.annotations.ApiOperation;

@Api(tags = "账户权限相关接口")
@RestController
@RequestMapping(value = "/permission")
public class PermissionApiServiceImpl extends RootApiService implements PermissionApiService {
    private static final Logger logger = LoggerFactory.getLogger(PermissionApiServiceImpl.class);

    @Resource
    private AccountBffService accountBffService;

    @Resource
    private GroupBffService groupBffService;

    @Resource
    private ResourceBffService resourceBffService;

    @Resource
    private IovPermissionService iovPermissionService;

    @Resource
    private TokenUtil tokenUtil;
    
    @Resource
    private OperationLogBffService operationLogBffService;

    /**
     * 账户登录
     *
     * @param params
     * @return
     */
    @Override
    @ApiOperation(value = "账户登录")
    @ApiImplicitParams({@ApiImplicitParam(name = "account", value = "账号", required = true, dataType = "String"),
            @ApiImplicitParam(name = "password", value = "用户密码", required = true, dataType = "String")})
    @PostMapping(value = "login")
    @OptionalLogConfig(methods="账户登录")
    public ResponseResult<AccountLoginVo> login(@RequestBody Map<String, Object> params) {
        ResponseResult<AccountLoginVo> result = new ResponseResult<>();
        try {
            params.put("systemType", SystemTypeEnum.OP);
            result.success(accountBffService.login(params));
        } catch (BizException e) {
            logger.error("[login]登录异常:", e);
            result.error(e.getExceptionCode(), e.getMessage());
        } catch (Exception e) {
            logger.error("[login]登录异常:", e);
            result.error("登录异常");
        }

        return result;
    }

    /**
     * 账户登出
     *
     * @return
     */
    @ApiOperation(value = "账户登出")
    @PostMapping(value = "/logOut")
    @Override
    @OptionalLogConfig(methods="账户登出")
    public ResponseResult<Boolean> logOut() {
        ResponseResult<Boolean> result = new ResponseResult<Boolean>();
        try {
            accountBffService.logOut();
            return result.success("成功", Boolean.TRUE);
        } catch (Exception e) {
            logger.error(e.getMessage(), e);
        }
        return result.error("失败", Boolean.FALSE);
    }

    @Override
    @ApiOperation(value = "获取后台用户")
    @ApiImplicitParams({
            @ApiImplicitParam(name = "systemType", value = "系统类型（1：op, 2：经销商）", required = true, dataType = "Integer"),
            @ApiImplicitParam(name = "realName", value = "真实姓名", required = false, dataType = "String"),
            @ApiImplicitParam(name = "status", value = "账号状态（0：启用， 1：禁用）", required = false, dataType = "Integer"),
            @ApiImplicitParam(name = "dealerId", value = "经销商Id", required = false, dataType = "Integer"),
            @ApiImplicitParam(name = "pageNum", value = "当前页", required = true, dataType = "Integer"),
            @ApiImplicitParam(name = "pageSize", value = "一页显示条数", required = true, dataType = "Integer")
    })
    @GetMapping(value = "/account/getAccountList")
    public ResponseResult<Paged<AccountVo>> getAccount(@RequestParam Map<String, Object> params, @RequestParam int pageNum, @RequestParam int pageSize) {
        ResponseResult<Paged<AccountVo>> result = new ResponseResult();
        try {
            return result.success(accountBffService.getAccountList(params, pageNum, pageSize));
        } catch (Exception e) {
            logger.error(e.getMessage(), e);
        }
        return result.error("获取失败");
    }

    @Override
    @ApiOperation(value = "添加用户")
    @PostMapping(value = "/account/createAccount")
    @OptionalLogConfig(methods="新增用户")
    public ResponseResult<Boolean> createAccount(@RequestBody @Valid AccountCreateVo vo) {
        return accountBffService.createAccount(vo);
    }

    @Override
    @ApiOperation(value = "修改用户")
    @PostMapping(value = "/account/modifyAccount")
    @OptionalLogConfig(methods="修改用户")
    public ResponseResult<Boolean> modifyAccount(@RequestBody @Valid AccountModifyVo vo) {
        return accountBffService.modifyAccount(vo);
    }

    @Override
    @ApiOperation(value = "重置密码")
    @PostMapping(value = "/account/modifyResetPassword")
    @OptionalLogConfig(methods="重置密码")
    public ResponseResult<Boolean> modifyResetPassword(@RequestBody AccountModifyVo vo) {
        return accountBffService.modifyResetPassword(vo);
    }

    @Override
    @ApiOperation(value = "修改密码")
    @PostMapping(value = "/account/modifyPassword")
    @OptionalLogConfig(methods="修改密码")
    public ResponseResult<Boolean> modifyPassword(@RequestBody ModifyPassowrdVo vo) {
        try {
            return accountBffService.modifyPassword(vo);
        } catch (Exception e) {
            logger.error(e.getMessage(), e);
        }
        return new ResponseResult<Boolean>().error("失败", Boolean.FALSE);
    }


    @Override
    @ApiOperation(value = "获取角色列表")
    @ApiImplicitParams({
            @ApiImplicitParam(name = "groupSystemType", value = "系统类型（1：op, 2：经销商, 3:车联网）", required = true, dataType = "Integer"),
            @ApiImplicitParam(name = "name", value = "角色名称", required = false, dataType = "String"),
            @ApiImplicitParam(name = "status", value = "角色状态（0：启用， 1：禁用）", required = false, dataType = "Integer"),
            @ApiImplicitParam(name = "dealerId", value = "经销商Id", required = false, dataType = "Integer"),
            @ApiImplicitParam(name = "pageNum", value = "当前页", required = true, dataType = "Integer"),
            @ApiImplicitParam(name = "pageSize", value = "一页显示条数", required = true, dataType = "Integer")
    })
    @GetMapping(value = "/group/getGroupList")
    public ResponseResult<Paged<GroupVo>> getGroupList(@RequestParam Map<String, Object> param, @RequestParam int pageNum, @RequestParam int pageSize) {
        ResponseResult<Paged<GroupVo>> result = new ResponseResult<>();
        try {
            return groupBffService.getGroupList(param, pageNum, pageSize);
        } catch (Exception e) {
            logger.error(e.getMessage(), e);
        }
        return result.error("获取失败");
    }

    @Override
    @ApiOperation(value = "添加角色")
    @PostMapping(value = "/group/createGroup")
    @OptionalLogConfig(methods="添加角色")
    public ResponseResult<Boolean> createGroup(@RequestBody GroupCreateVo vo) {
        return groupBffService.createGroup(vo);
    }

    @Override
    @ApiOperation(value = "修改角色")
    @PostMapping(value = "/group/modifyGroup")
    @OptionalLogConfig(methods="修改角色")
    public ResponseResult<Boolean> modifyGroup(@RequestBody GroupModifyVo vo) {
        return groupBffService.modifyGroup(vo);
    }

    @Override
    @ApiOperation(value = "用户修改页获取角色")
    @ApiImplicitParams({
            @ApiImplicitParam(name = "systemType", value = "系统类型（1：op, 2：经销商）", required = true, dataType = "Integer"),
            @ApiImplicitParam(name = "account", value = "用户名", required = false, dataType = "String"),
            @ApiImplicitParam(name = "dealerId", value = "经销商Id", required = false, dataType = "Integer")
    })
    @GetMapping(value = "/account/getGroupListInModifyAccountPage")
    public ResponseResult<OpGroupAndIovGroupVo> getGroupListInModifyAccountPage(@RequestParam int systemType, @RequestParam(required = false, defaultValue = "") String account, @RequestParam(required = false, defaultValue = "0") int dealerId) {
        ResponseResult<OpGroupAndIovGroupVo> result = new ResponseResult<>();
        if (systemType <= 0) {
            return result.error("系统类型不能为空");
        }
        if (systemType == SystemTypeEnum.DEALER.getValue() && (dealerId <= 0)) {
            return result.error("经销商不能为空");
        }

        try {
            return result.success("查询成功", groupBffService.getGroupListInModifyAccountPage(systemType, dealerId, account));
        } catch (Exception e) {
            logger.error(e.getMessage(), e);
        }
        return result.error("查询失败");
    }

    @Override
    @ApiOperation(value = "角色配置页获取权限")
    @ApiImplicitParams({
            @ApiImplicitParam(name = "groupId", value = "角色id", required = true, dataType = "Integer"),
            @ApiImplicitParam(name = "systemType", value = "系统类型（1：op，2：经销商，3：车联网）", required = true, dataType = "Integer")
    })
    @GetMapping(value = "/group/getPermissionTree")
    public ResponseResult<GroupBindResourceVo> getPermissionTree(@RequestParam int groupId, @RequestParam int systemType) {
        ResponseResult<GroupBindResourceVo> result = new ResponseResult();
        if (systemType <= 0 || groupId <= 0) {
            return result.error("角色id与系统类型校验失败");
        }

        try {
            return result.success("获取成功", groupBffService.getPermissionTree(groupId, systemType));
        } catch (Exception e) {
            logger.error(e.getMessage(), e);
        }
        return result.error("获取失败");
    }

    @Override
    @ApiOperation(value = "获得脱敏字段列表与角色已绑定脱敏字段")
    @ApiImplicitParams({
            @ApiImplicitParam(name = "groupId", value = "角色id", required = true, dataType = "Integer")
    })
    @GetMapping(value = "/group/getDesenseByGroupId")
    public ResponseResult<Paged<DesenseVo>> getDesenseByGroupId(@RequestParam int groupId) {
        ResponseResult<Paged<DesenseVo>> result = new ResponseResult();
        if (groupId <= 0) {
            return result.error("角色id不能为空");
        }

        try {
            List<DesenseVo> dataList = groupBffService.getDesenseByGroupId(groupId);
            return result.success("成功", new Paged<DesenseVo>(dataList, dataList.size(), dataList.size()));
        } catch (Exception e) {
            logger.error(e.getMessage(), e);
        }
        return result.error("失败");
    }

    @Override
    @ApiOperation(value = "为角色绑定脱敏字段")
    @PostMapping(value = "/group/createBatchGroupDesense")
    public ResponseResult<Boolean> createBatchGroupDesense(@RequestBody(required = true) GroupBindVo vo) {
        ResponseResult<Boolean> result = new ResponseResult<Boolean>();
        if (vo.getGroupId() <= 0) {
            return result.error("角色id不能为空");
        }
        try {
            boolean createResult = groupBffService.createBatchGroupDesense(vo.getGroupId(), vo.getDataIds());
            if (createResult) {
                return result.success("成功", Boolean.TRUE);
            }
        } catch (Exception e) {
            logger.error(e.getMessage(), e);
        }
        return result.error("失败", Boolean.FALSE);
    }

    @Override
    @ApiOperation(value = "为角色绑定权限")
    @PostMapping(value = "/group/createBatchGroupResource")
    public ResponseResult<Boolean> createBatchGroupResource(@RequestBody(required = true) GroupBindVo vo) {
        ResponseResult<Boolean> result = new ResponseResult<Boolean>();
        if (vo.getGroupId() <= 0) {
            return result.error("角色id不能为空");
        }
        try {
            return groupBffService.createBatchGroupResource(vo);
        } catch (Exception e) {
            logger.error(e.getMessage(), e);
        }
        return result.error("失败", Boolean.FALSE);
    }

    /**
     * 获得op左侧菜单树
     *
     * @return
     */
    @Override
    @ApiOperation(value = "获取左侧菜单树")
    @PostMapping(value = "/getMenuList")
    public ResponseResult<List<ResourceDto>> getMenuList() {
        ResponseResult<List<ResourceDto>> result = new ResponseResult<List<ResourceDto>>();
        try {
            List<ResourceDto> menuTree = resourceBffService.getMenuTree();
            return result.success("成功", menuTree);
        } catch (Exception e) {
            logger.error(e.getMessage(), e);
        }
        return result.error("失败");
    }

    @Override
    @ApiOperation(value = "登录日志列表")
    @ApiImplicitParams({@ApiImplicitParam(name = "account", value = "用户帐号", required = false, dataType = "String"),
            @ApiImplicitParam(name = "loginTimeStart", value = "开始时间", required = false, dataType = "String"),
            @ApiImplicitParam(name = "loginTimeEnd", value = "结束时间", required = false, dataType = "String"),
            @ApiImplicitParam(name = "pageNum", value = "页码", required = true, dataType = "Integer"),
            @ApiImplicitParam(name = "pageSize", value = "每页条数", required = true, dataType = "Integer")
    })
    @GetMapping(value = "/login/log/list")
    public ResponseResult<Paged<AccountLoginLogVo>> getLoignLog(@RequestParam Map<String, Object> params,
                                                                @RequestParam(defaultValue = "1") Integer pageNum, @RequestParam(defaultValue = "10") Integer pageSize) {
        ResponseResult<Paged<AccountLoginLogVo>> result = new ResponseResult<>();
        try {
            result.success(accountBffService.getLoignLog(params, pageNum, pageSize));
        } catch (BizException e) {
            logger.error("[getLoignLog]获取登录日志列表异常", e);
            result.error(e.getExceptionCode(), e.getMessage());
        } catch (Exception e) {
            logger.error("[getLoignLog]获取登录日志列表异常", e);
            result.error("获取登录日志列表异常");
        }
        return result;
    }

    @ApiOperation(value = "根据权限id获取页签列表")
    @ApiImplicitParam(name = "permissionId", value = "权限id", required = false, dataType = "Integer")
    @GetMapping(value = "/sign/page")
    @Override
    public ResponseResult<List<TabVo>> getTabList(@RequestParam Integer permissionId) {
        ResponseResult<List<TabVo>> result = new ResponseResult<>();
        try {
            result = accountBffService.getTabList(permissionId,tokenUtil.getUser().getGroupId());
        } catch (BizException e) {
            logger.error("[getTabList]根据权限id获取页签列表异常", e);
            result.error(e.getExceptionCode(), e.getMessage());
        } catch (Exception e) {
            logger.error("[getTabList]根据权限id获取页签列表异常", e);
            result.error("根据权限id获取页签列表异常");
        }
        return result;
    }
    
    @Override
    @ApiOperation(value = "获取操作日志列表信息")
    @ApiImplicitParams({
            @ApiImplicitParam(name = "accountName", value = "操作人姓名", required = false, dataType = "String"),
            @ApiImplicitParam(name = "operationStartDate", value = "开始时间", required = false, dataType = "String"),
            @ApiImplicitParam(name = "operationEndDate", value = "结束时间", required = false, dataType = "String"),
            @ApiImplicitParam(name = "pageNum", value = "页码", required = true, dataType = "Integer"),
            @ApiImplicitParam(name = "pageSize", value = "每页条数", required = true, dataType = "Integer")

    })
    @GetMapping(value = "/operation/log/list")
    public ResponseResult<Paged<OperationLogVo>> getOperationLog(@RequestParam(required = false) Map<String, Object> map,
                                                                           @RequestParam(required = true) Integer pageNum, @RequestParam(required = true) Integer pageSize) {
        
		if(null==pageNum || pageNum < 1 ) {
			pageNum=1;
		}
		if(null==pageSize || pageSize <= 0) {
			pageSize=10;
		}
		String operationStartDate = ObjectCastUtil.castString(map.get("operationStartDate"));
		if (StringUtils.isNoneBlank(operationStartDate)) {
			map.put("operationStartDate", DateUtil.parseDate(operationStartDate).atStartOfDay());
		}
		String operationEndDate = ObjectCastUtil.castString(map.get("operationEndDate"));
		if (StringUtils.isNoneBlank(operationEndDate)) {
			map.put("operationEndDate", DateUtil.getDayEnd(DateUtil.parseDate(operationEndDate).atStartOfDay()));
		}

    	ResponseResult<Paged<OperationLogVo>> result = new ResponseResult<>();
        try {
            result.success(operationLogBffService.getOperationLog(map, pageNum, pageSize));
        } catch (BizException e) {
            logger.error("[list]获取操作信息异常", e);
            result.error(e.getExceptionCode(), e.getMessage());
        } catch (Exception e) {
            logger.error("[list]获取操作列表信息异常", e);
            result.error("获取操作列表信息异常");
        }
        return result;
    }

}
